package me.zhanshi123.enchantfix;

import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketEvent;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

import java.util.ArrayList;
import java.util.List;

public class Protocol {
    private void hideEnchants(ItemStack itemStack, ItemMeta itemMeta) {
        List<String> enchants = new ArrayList<>();
        itemStack.getEnchantments().forEach((key, value) -> enchants.add(EnchantFix.getConfigManager().getFormat().replace("{enchant}", EnchantNameMapper.getEnchantName(key))
                .replace("{rome}", intToRoman(value))
                .replace("{arab}", String.valueOf(value))));
        replacePlaceholders(itemStack, itemMeta, enchants);
    }

    public void init() {
        if (Integer.parseInt(EnchantFix.MINECRAFT_VERSION) <= 8) {
            ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(EnchantFix.getInstance(), PacketType.Play.Server.SET_SLOT, PacketType.Play.Server.WINDOW_ITEMS) {
                @Override
                public void onPacketSending(PacketEvent event) {
                    if (event.getPlayer().getGameMode() == GameMode.CREATIVE) {
                        return;
                    }
                    if (event.getPacket().getType() == PacketType.Play.Server.WINDOW_ITEMS) {
                        ItemStack[] itemStacks = event.getPacket().getItemArrayModifier().read(0);
                        for (int i = 0; i < itemStacks.length; i++) {
                            ItemStack itemStack = itemStacks[i];
                            handle(itemStack);
                            itemStacks[i] = itemStack;
                        }
                        event.getPacket().getItemArrayModifier().write(0, itemStacks);
                    } else {
                        ItemStack itemStack = event.getPacket().getItemModifier().read(0);
                        handle(itemStack);
                        event.getPacket().getItemModifier().write(0, itemStack);
                    }
                }
            });
            return;
        }
        ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(EnchantFix.getInstance(), PacketType.Play.Server.SET_SLOT, PacketType.Play.Server.WINDOW_ITEMS) {
            @Override
            public void onPacketSending(PacketEvent event) {
                if (event.getPlayer().getGameMode() == GameMode.CREATIVE) {
                    return;
                }
                if (event.getPacket().getType() == PacketType.Play.Server.WINDOW_ITEMS) {
                    List<ItemStack> itemStacks = new ArrayList<>();
                    event.getPacket().getItemListModifier().read(0).forEach(itemStack -> {
                        ItemStack item = itemStack.clone();
                        if (!item.getType().equals(Material.AIR)) {
                            if (item.getEnchantments().size() != 0) {
                                ItemMeta itemMeta = item.getItemMeta();
                                if (!itemMeta.hasItemFlag(ItemFlag.HIDE_ENCHANTS)) {
                                    hideEnchants(item, itemMeta);
                                }
                            }
                        }
                        itemStacks.add(item);
                    });
                    event.getPacket().getItemListModifier().write(0, itemStacks);
                } else {
                    if (event.getPlayer().getGameMode() == GameMode.CREATIVE) {
                        return;
                    }
                    ItemStack itemStack = event.getPacket().getItemModifier().read(0);
                    handle(itemStack);
                    event.getPacket().getItemModifier().write(0, itemStack);
                }
            }
        });
    }

    private void handle(ItemStack itemStack) {
        if (itemStack != null) {
            if (!itemStack.getType().equals(Material.AIR)) {
                if (itemStack.getEnchantments().size() != 0) {
                    ItemMeta itemMeta = itemStack.getItemMeta();
                    if (!itemMeta.hasItemFlag(ItemFlag.HIDE_ENCHANTS)) {
                        hideEnchants(itemStack, itemMeta);
                    }
                }
            }
        }
    }

    private void replacePlaceholders(ItemStack itemStack, ItemMeta itemMeta, List<String> enchants) {
        List<String> lore = new ArrayList<>();
        lore.addAll(enchants);
        itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
        if (itemMeta.hasLore()) {
            lore.addAll(itemMeta.getLore());
        }
        itemMeta.setLore(lore);
        itemStack.setItemMeta(itemMeta);
    }

    private String intToRoman(int num) {
        String[] digit = {"", "I", "II", "III", "IV", "V", "VI", "VII",
                "VIII", "IX"};
        String[] ten = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX",
                "XC"};
        String[] hundred = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC",
                "DCCC", "CM"};
        String[] thousand = {"", "M", "MM", "MMM"};
        return thousand[num / 1000] + hundred[num % 1000 / 100] + ten[num % 100 / 10] + digit[num % 10];
    }

}
